/**
 * Copyright (c) 2006 RiseSoft Co.,Ltd  
 * $Header$
 */
package net.risesoft.risebi.collection.web.admin;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.Cookie;
import net.risesoft.risebi.collection.commons.constants.SystemConstants;
import net.risesoft.risebi.collection.commons.memcached.MemCachedService;
import net.risesoft.risebi.collection.model.Application;
import net.risesoft.risebi.collection.model.Module;
import net.risesoft.risebi.collection.model.ObjectPermission;
import net.risesoft.risebi.collection.model.Service;
import net.risesoft.risebi.collection.model.User;
import net.risesoft.risebi.collection.service.ApplicationManager;
import net.risesoft.risebi.collection.service.ModuleManager;
import net.risesoft.risebi.collection.service.PrivilegeManager;
import net.risesoft.risebi.collection.service.ServiceManager;
import net.risesoft.risebi.collection.web.BaseAction;
import net.risesoft.risebi.commons.struts2extension.Trimable;
import net.risesoft.risebi.commons.util.ContextUtil;
import net.risesoft.risebi.commons.util.JSONUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONFunction;
import net.sf.json.JSONObject;
import net.risesoft.risebi.commons.util.GUID;
import org.apache.commons.beanutils.LazyDynaBean;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.web.util.WebUtils;
import com.opensymphony.xwork2.ActionInvocation;

/**
 * 模块管理action
 *
 * @author <a href="mailto: dingzhaojun2046@hotmail.com">丁兆俊</a>
 * @version $Revision$
 * 
 */
@Namespace("/admin/ModuleAction")
public class ModuleAction extends BaseAction implements Trimable {	
	private static final long serialVersionUID = 605298473563075550L;	
	private static Log log = LogFactory.getLog(ModuleAction.class);
	
	private Module module;
	
	private ApplicationManager applicationManager;
	private ModuleManager moduleManager;
	private PrivilegeManager privilegeManager;
	private ServiceManager serviceManager;
	private MemCachedService memCachedService;
		
	private String currentServiceGuid = "";
	private String currentAppGuid = "";
	private String currentAppName = "";
	private String chooseServiceApp = "1";
	private boolean isServiceUser = false;
	private boolean isTopModule = false;

	@Action(value="prepareModuleList4SystemUser",
			results={@Result(name="success", location="/admin/module/moduleList4SystemUser.jsp")}
	)
	public String prepareModuleList4SystemUser() throws Exception {
		return SUCCESS;
	}

	@Action(value="prepareModuleList4ServiceUser",
			results={@Result(name="success", location="/admin/module/moduleList4ServiceUser.jsp")}
	)
	public String prepareModuleList4ServiceUser() throws Exception {
		return SUCCESS;
	}
	
	@Action(value="prepareModuleIndex",
			results={@Result(name="success", location="/admin/module/moduleIndex.jsp")}
	)
	public String prepareModuleIndex() throws Exception {
		return SUCCESS;
	}

	@Action(value="prepareModuleEdit",
			results={@Result(name="success", location="/admin/module/moduleEdit.jsp")}
	)
	public String prepareModuleEdit() throws Exception {
		if(module.getGuid()==null || module.getGuid().trim().length()==0){
			module.setGuid("NEW");			
		}else{
			module = (Module)moduleManager.getObject(Module.class, module.getGuid());
			
		}
		if(module.getEnabled()==null){
			module.setEnabled(true);
		}
		if(module.getTabIndex()==null){
			module.setTabIndex(Double.valueOf("1"));
		}
		
		return SUCCESS;
	}

	@Action(value="edit")
	public String edit() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			if(module.getGuid()==null || module.getGuid().trim().length()==0 || module.getGuid().startsWith("NEW")){
				module.setGuid(new GUID().toString());
			}
			
			moduleManager.saveObject(module);	
			
			ldb.set("guid", module.getGuid());
			ldb.set("parentGuid", module.getParentGuid());
			ldb.set("name", module.getName());
			ldb.set("url", module.getUrl());
			ldb.set("description", module.getDescription());
			ldb.set("enabled", module.getEnabled());
			ldb.set("iconName", module.getIconName());			
			ldb.set("tabIndex", module.getTabIndex());	
			
			boolean isleaf = true;
			int count = moduleManager.getCount("select count(*) from Module t where t.parentModule.guid = '" + module.getGuid() + "'");
			if(count>0){
				isleaf = false;
			}
			ldb.set("isleaf", isleaf);
			
			ldb.set("success", true);
			ldb.set("reason", "修改成功!");
			
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
		}

		return AJAX;
	}

	@Action(value="getSubModules")
	public String getSubModules() throws Exception {
		try{
			List<Module> lst = null;
			if(this.active_node_id==null || this.active_node_id.trim().length()==0){
				lst = moduleManager.find("from Module m where m.parentModule.guid=null or trim(m.parentModule.guid)='' order by m.tabIndex asc");
			}else{
				lst = moduleManager.find("from Module m where m.parentModule.guid='" + this.active_node_id + "' order by m.tabIndex asc");
			}
			
			String serviceGuid = null;
			Service service = this.getDefaultService();
			if(service!=null){
				serviceGuid = service.getGuid();
			}
			lst = privilegeManager.getAllowedList(lst, ObjectPermission.OBJECTTYPE_MODULE, getSessionUser(), serviceGuid);
			
			ArrayList al = new ArrayList();	
			for(Module m : lst){
				String moduleName = m.getName();
				if(isServiceUser==true){					
					if(moduleName.equalsIgnoreCase("系统管理")){
						continue;
					}
				}
				
				LazyDynaBean ldb = new LazyDynaBean();
				ldb.set("guid", m.getGuid());
				ldb.set("parentGuid", m.getParentGuid());
				ldb.set("name", moduleName);
				ldb.set("url", m.getUrl());
				ldb.set("description", m.getDescription());
				ldb.set("iconName", m.getIconName());
				ldb.set("enabled", m.getEnabled());
				ldb.set("tabIndex", m.getTabIndex());
				
				boolean isleaf = true;
				int count = moduleManager.getCount("select count(*) from Module t where t.parentModule.guid = '" + m.getGuid() + "'");
				if(count>0){
					isleaf = false;
				}
				ldb.set("isleaf", isleaf);
				
				al.add(ldb);
			}	
			this.json = JSONUtil.getJsonString(null,null,al);
		}catch(Exception e){
			this.json = "[]";
		} 
		
		return AJAX;
	}	

	@Action(value="getTopModules")
	public String getTopModules() throws Exception {
		try{
			User user = this.getSessionUser();
			List<Module> modules = moduleManager.getNextScopeChildren("", user);
			
			JSONArray jsonArray = new JSONArray();
			JSONObject jsonObject = new JSONObject();
			jsonObject.element("xtype", "panel");
			String html = "";
			for(Module m : modules){
				if("企业填报".equals(m.getName())){
					continue;
				}
				if(html.length()==0){
					html = "<a id='" + m.getName() + "' guid='" + m.getGuid() + "' text='" + m.getName() + "' url='" + m.getUrl() + "' class='" + m.getIconName() + " mysize16 a02' href='javascript:void(0);' onclick='gotoModuleUrl(\"" + m.getGuid() +"\",\"" + m.getName() +"\",\"" + m.getUrl() +"\");'>"+m.getName()+"</a>";
				}else{
					html += "&nbsp;&nbsp;<a id='" + m.getName() + "' guid='" + m.getGuid() + "' text='" + m.getName() + "' url='" + m.getUrl() + "' class='" + m.getIconName() + " mysize16 a02' href='javascript:void(0);' onclick='gotoModuleUrl(\"" + m.getGuid() +"\",\"" + m.getName() +"\",\"" + m.getUrl() +"\");'>"+m.getName()+"</a>";
				}
				
				jsonObject.element("html", html);			
			}
			jsonArray.add(jsonObject);
			this.json = jsonArray.toString();
		}catch(Exception e){
			this.json = "[]";
		} 
		
		return AJAX;
	}	

	public String getTopModules2222() throws Exception {
		try{
			User user = this.getSessionUser();
			List<Module> modules = moduleManager.getNextScopeChildren("", user);
			
			JSONArray jsonArray = new JSONArray();
			for(Module m : modules){
				if("企业填报".equals(m.getName())){
					continue;
				}
				
				JSONObject jsonObject = new JSONObject();
				jsonObject.element("id", m.getGuid())
					.element("xtype", "button")
					.element("text", m.getName())
					.element("width", 60)
					.element("iconCls", m.getIconName())
					.element("scale", "small")
					.element("url", m.getUrl())
					.element("handler", new JSONFunction(new String[]{"btn","e"},"gotoModuleUrl(btn,e);"));
				jsonArray.add(jsonObject);
			}	
			this.json = jsonArray.toString();
		}catch(Exception e){
			this.json = "[]";
		} 
		
		return AJAX;
	}
	
	@Action(value="checkServiceApp")
	public String checkServiceApp() throws Exception {
		try{
			Module m = (Module)moduleManager.getObject(Module.class, this.node);
			int chooseServiceApp = 0;
			try{
				String url = m.getUrl();
				int i = url.indexOf("chooseServiceApp");
				if(i>0){
					int j = url.indexOf("=", i);
					if(j>0){
						int k = url.indexOf("&",j);
						if(k==-1){
							chooseServiceApp = Integer.parseInt(url.substring(j+1));
						}else{
							chooseServiceApp = Integer.parseInt(url.substring(j+1,k));
						}						
					}
				}
			}catch(Exception e){
				chooseServiceApp = 0;
			} 
			
			if(chooseServiceApp==1){
				if (this.getDefaultService() == null) {
					this.json = "{success : false, chooseServiceApp : 1, reason : '请您选择一个服务。'}";
					return AJAX;
				}				
			}else if(chooseServiceApp==2){
				if (this.getDefaultService() == null || this.getDefaultApp() == null) {
					this.json = "{success : false, chooseServiceApp : 2, reason : '请您选择一个服务和应用。'}";
					return AJAX;
				}
			}
			
			this.json = "{success : true}";
		}catch(Exception e){
			this.json = "{success : false, reason : '" + e.getMessage() + "'}";
		} 
		
		return AJAX;
	}

	@Action(value="getModuleTreeNodes")
	public String getModuleTreeNodes() throws Exception {
		try{
			List<Module> list = null;
			if("moduleTreeRootNode".equals(this.node)){
				if(this.source.length()==0){
					return "getModuleTreeNodes";
				}else{
					list = moduleManager.getNextScopeChildren(this.source,  this.getSessionUser());
				}
			}else{
				list = moduleManager.getNextScopeChildren(this.node,  this.getSessionUser());
			}				
				
			JSONArray jsonArray = new JSONArray();
			for(Module t : list){
				boolean isleaf = true;
				int count = moduleManager.getCount("select count(*) from Module t where t.parentModule.guid = '" + t.getGuid() + "'");
				if(count>0){
					isleaf = false;
				}
				
				JSONObject jsonObj = new JSONObject();
				jsonObj.element("id", t.getGuid());
				jsonObj.element("text", t.getName());
				jsonObj.element("url", t.getUrl());
				jsonObj.element("singleClickExpand", true);
				jsonObj.element("qtip", "");
				jsonObj.element("permission", 4);
				jsonObj.element("iconCls", t.getIconName());
				jsonObj.element("disabled", !t.getEnabled());
				jsonObj.element("leaf", isleaf);
				jsonArray.add(jsonObj);
			}	
			this.json = jsonArray.toString();			
		}catch(Exception e){
			this.json = "[]";
		} 
		
		return AJAX;
	}

	@Action(value="prepareChooseServiceApp",
			results={@Result(name="success", location="/admin/chooseServiceApp.jsp")}
	)
	public String prepareChooseServiceApp() throws Exception {
		User user = getSessionUser();
		List<Service> list = serviceManager.getServicesWithPermission(user);
		json = JSONUtil.getJsonString("include", "guid,name", list);
		
		if(this.getDefaultService()!=null){
			this.currentServiceGuid = this.getDefaultService().getGuid();
		}
		if(this.getDefaultApp()!=null){
			this.currentAppGuid = this.getDefaultApp().getGuid();
			this.currentAppName = this.getDefaultApp().getChineseName();
		}
		
		return SUCCESS;
	}

	@Action(value="saveServiceApp")
	public String saveServiceApp() throws Exception {
		String serviceName = "";
		String appName = "";
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			String uKey = null;
			User user = this.getSessionUser();
			
			if(SystemConstants.REPORT_CLUSTERED){
				Cookie c = WebUtils.getCookie(ServletActionContext.getRequest(), "riseSessionId");
				uKey = c.getValue() + "u";
			}
			Date expiry = new Date(12 * 60 * 60 * 1000);	
			
			Service service = (Service) serviceManager.getObject(Service.class, this.source);
			Service newService = service.cloneNoPersistence();
			user.setDefaultService(newService);
			serviceName = service.getName();
			
			if(this.node==null || this.node.length()==0){
				user.setDefaultApp(null);
			}else{
				Application defaultApp = (Application)applicationManager.getObject(Application.class, this.node);
				Application newApplication = defaultApp.cloneNoPersistence();
				user.setDefaultApp(newApplication);			
				appName = defaultApp.getChineseName();
			}
			
			if(SystemConstants.REPORT_CLUSTERED){
				memCachedService.setMemCachedValue(uKey, user, expiry);
			}
			
			ldb.set("success", true);
			ldb.set("reason", "success");
			ldb.set("serviceName", serviceName);
			ldb.set("appName", appName);
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
		}
		
		this.json = JSONObject.fromObject(ldb).toString();
		return AJAX;
	}
	
	@Action(value="remove")
	public String remove() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			moduleManager.removeObject(Module.class, node); 		
			
			ldb.set("success", true);
			ldb.set("reason", "删除模块成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}

		return AJAX;
	}

	@Action(value="insertOrUpdate")
	public String insertOrUpdate() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			Module[] ms = (Module[])JSONUtil.stringToArray(json, Module.class);
			for (Module m : ms){
				moduleManager.saveObject(m);
			}
			
			ldb.set("success", true);
			ldb.set("reason", "保存模块成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}

		return AJAX;
	}

	@Action(value="updateModuleTabIndex")
	public String updateModuleTabIndex() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			Module[] ms = (Module[])JSONUtil.stringToArray(json, Module.class);
			for (Module m : ms){
				Module module = (Module)moduleManager.getObject(Module.class, m.getGuid());
				module.setTabIndex(m.getTabIndex());
				moduleManager.saveObject(module);
			}
			
			ldb.set("success", true);
			ldb.set("reason", "保存模块成功!");
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
		}

		return AJAX;
	}

	@Action(value="export")
	public String export() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			List<Module> ms = moduleManager.getObjects(Module.class);
			String jsonModules = JSONUtil.getJsonString("include", "guid,parentGuid,name,enabled,description,url,iconName,tabIndex", ms);
			String filePath = this.getRealPath();
	        if(!filePath.endsWith(File.separator)){
	        	filePath = filePath + File.separator;
	        }
			filePath = filePath + "modules.json";
			
			FileOutputStream fos = new FileOutputStream(filePath);
	        OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
	        osw.write(jsonModules);
	        osw.close();
	        fos.close();
	        
			ldb.set("success", true);
			ldb.set("reason", "导出模块成功! 文件保存在：\r\n" + filePath);
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
			e.printStackTrace();
		}

		return AJAX;
	}

	@Action(value="importFromJson")
	public String importFromJson() throws Exception {
		LazyDynaBean ldb = new  LazyDynaBean();
		try{
			String filePath = this.getRealPath();
	        if(!filePath.endsWith(File.separator)){
	        	filePath = filePath + File.separator;
	        }
			filePath = filePath + "modules.json";
			File f = new File(filePath);
			if(f.exists()){
				//moduleManager.execute("delete Module");
				List lst = moduleManager.getObjects(Module.class);
				moduleManager.removeObjects(lst);
				
				FileInputStream fis = new FileInputStream(f);
				String jsonModules = IOUtils.toString(fis, "utf-8");
		        fis.close();
		        
				Module[] ms = (Module[])JSONUtil.stringToArray(jsonModules, Module.class);
				for (Module m : ms){
					moduleManager.saveObject(m);
				}		        
				
				ldb.set("success", true);
				ldb.set("reason", "导入模块成功!");				
			}else{
				ldb.set("success", false);
				ldb.set("reason", "没有找到这个文件：\r\n" + filePath);				
			}
			this.json = JSONObject.fromObject(ldb).toString();
		}catch(Exception e){
			ldb.set("success", false);
			ldb.set("reason", e.getMessage());
			this.json = JSONObject.fromObject(ldb).toString();
		}

		return AJAX;
	}

	/* (non-Javadoc)
	 * @see net.risesoft.commons.struts2extension.Trimable#afterTrim(com.opensymphony.xwork2.ActionInvocation)
	 */
	public void afterTrim(ActionInvocation invocation) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see net.risesoft.commons.struts2extension.Trimable#preTrim(com.opensymphony.xwork2.ActionInvocation)
	 */
	public boolean preTrim(ActionInvocation invocation) {
		return true;
	}

	public void setModuleManager(ModuleManager moduleManager) {
		this.moduleManager = moduleManager;
	}

	public ModuleManager getModuleManager() {
		return moduleManager;
	}

	public PrivilegeManager getPrivilegeManager() {
		return privilegeManager;
	}

	public void setPrivilegeManager(PrivilegeManager privilegeManager) {
		this.privilegeManager = privilegeManager;
	}

	public ServiceManager getServiceManager() {
		return serviceManager;
	}

	public void setServiceManager(ServiceManager serviceManager) {
		this.serviceManager = serviceManager;
	}

	public MemCachedService getMemCachedService() {
		return memCachedService;
	}

	public void setMemCachedService(MemCachedService memCachedService) {
		this.memCachedService = memCachedService;
	}

	public ApplicationManager getApplicationManager() {
		return applicationManager;
	}

	public void setApplicationManager(ApplicationManager applicationManager) {
		this.applicationManager = applicationManager;
	}

	public String getCurrentServiceGuid() {
		return currentServiceGuid;
	}

	public void setCurrentServiceGuid(String currentServiceGuid) {
		this.currentServiceGuid = currentServiceGuid;
	}

	public String getCurrentAppGuid() {
		return currentAppGuid;
	}

	public void setCurrentAppGuid(String currentAppGuid) {
		this.currentAppGuid = currentAppGuid;
	}

	public String getCurrentAppName() {
		return currentAppName;
	}

	public void setCurrentAppName(String currentAppName) {
		this.currentAppName = currentAppName;
	}

	public String getChooseServiceApp() {
		return chooseServiceApp;
	}

	public void setChooseServiceApp(String chooseServiceApp) {
		this.chooseServiceApp = chooseServiceApp;
	}

	public Module getModule() {
		return module;
	}

	public void setModule(Module module) {
		this.module = module;
	}

	public boolean isServiceUser() {
		return isServiceUser;
	}

	public void setServiceUser(boolean isServiceUser) {
		this.isServiceUser = isServiceUser;
	}

	public boolean isTopModule() {
		return isTopModule;
	}

	public void setTopModule(boolean isTopModule) {
		this.isTopModule = isTopModule;
	}

		
}
